package com.lebang.medicalInquiry.utils;


import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

@Slf4j
public class XmlDomUtil {


    public static String createDom(String name, String style, String volume, String rate, String pitch, String styledegree, String role, String text) {
        Document doc = null;
        Element speak, voice, emotion, prosody, p;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            doc = builder.newDocument();
            if (doc != null) {
                speak = doc.createElement("speak");
                speak.setAttribute("version", "1.0");
                speak.setAttribute("xmlns", "http://www.w3.org/2001/10/synthesis");
                speak.setAttribute("xmlns:mstts", "https://www.w3.org/2001/mstts");
                speak.setAttribute("xmlns:emo", "http://www.w3.org/2009/10/emotionml");
                speak.setAttribute("xml:lang", "zh-CN");
                String[] split = text.split("[！!？?:；、丶`。.，,;’\"‘“”]+");
                if (!TextUtil.isEmpty(name)) {
                    voice = doc.createElement("voice");
                    p = doc.createElement("p");
                    voice.appendChild(p);
                    voice.setAttribute("name", name);
                    if (TextUtil.isEmpty(style) && TextUtil.isEmpty(role) && TextUtil.isEmpty(volume) && TextUtil.isEmpty(pitch) && TextUtil.isEmpty(rate)) {
                        for (int i = 0; i < split.length; i++) {
                            String s1 = split[i];
                            if (!TextUtil.isEmpty(s1)) {
                                Element breakValue = doc.createElement("break");
                                breakValue.setAttribute("time", "200ms");
//                                Element phoneme = doc.createElement("phoneme");
//                                phoneme.setAttribute("alphabet","sapi");
//                                phoneme.setAttribute("ph","zhuó");
//                                phoneme.appendChild(doc.createTextNode(s1));
                                p.appendChild(doc.createTextNode(s1));
                                p.appendChild(breakValue);
                            }
                        }
                    } else {
                        emotion = doc.createElement("mstts:express-as");
                        p.appendChild(emotion);
                        // 如果为空 还设置的话会导致role不起作用
                        if (!TextUtil.isEmpty(style)) {
                            emotion.setAttribute("style", style);
                        }
                        emotion.setAttribute("role", role);


                        if (!TextUtil.isEmpty(volume) || !TextUtil.isEmpty(rate) || !TextUtil.isEmpty(pitch)) {
                            emotion.setAttribute("styledegree", styledegree);
                            prosody = doc.createElement("prosody");
                            p.appendChild(prosody);
                            if (!TextUtil.isEmpty(volume)) {
                                prosody.setAttribute("volume", volume);
                            }
                            if (!TextUtil.isEmpty(rate)) {
                                prosody.setAttribute("rate", rate);
                            }
                            if (!TextUtil.isEmpty(pitch)) {
                                prosody.setAttribute("pitch", pitch);
                            }
//                            prosody.setAttribute("volume", volume);
                            for (int i = 0; i < split.length; i++) {
                                String s1 = split[i];
                                if (!TextUtil.isEmpty(s1)) {
                                    Element breakValue = doc.createElement("break");
                                    if( s1.contains("2")){
                                        String[] split1 = s1.split("2");
                                        for (int i1 = 0; i1 < split1.length; i1++) {
                                            prosody.appendChild(doc.createTextNode(split1[i1]));
                                            if(i1!=split1.length-1){
                                                Element breakValue1 = doc.createElement("break");
                                                breakValue1.setAttribute("time","10ms");
                                                prosody.appendChild(breakValue1);
                                            }
                                        }
                                    }else{
                                        breakValue.setAttribute("time","200ms");
                                        prosody.appendChild(doc.createTextNode(s1));
                                        prosody.appendChild(breakValue);
                                    }



                                }
                            }
                            emotion.appendChild(prosody);
                        } else {
                            for (int i = 0; i < split.length; i++) {
                                String s1 = split[i];
                                if (!TextUtil.isEmpty(s1)) {
                                    Element breakValue = doc.createElement("break");
                                    breakValue.setAttribute("time", "200ms");
                                    emotion.appendChild(doc.createTextNode(s1));
                                    emotion.appendChild(breakValue);

                                }
                            }
                        }

                    }
                    speak.appendChild(voice);
                } else {
                    return null;
                }
                doc.appendChild(speak);
            }
        } catch (ParserConfigurationException e) {
            log.error("Create ssml document failed: {}", e.getMessage());
            return null;
        }
        return transformDom(doc);
    }

    public static String createDom1(String name, String style, String volume, String rate, String pitch, String styledegree, String role, String text) {
        Document doc = null;
        Element speak, voice, emotion, prosody;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            doc = builder.newDocument();
            if (doc != null) {
                speak = doc.createElement("speak");
                speak.setAttribute("version", "1.0");
                speak.setAttribute("xmlns", "http://www.w3.org/2001/10/synthesis");
                speak.setAttribute("xmlns:mstts", "https://www.w3.org/2001/mstts");
                speak.setAttribute("xmlns:emo", "http://www.w3.org/2009/10/emotionml");
                speak.setAttribute("xml:lang", "zh-CN");
                if (!TextUtil.isEmpty(name)) {
                    voice = doc.createElement("voice");
                    voice.setAttribute("name", name);
                    if (TextUtil.isEmpty(style) && TextUtil.isEmpty(role) && TextUtil.isEmpty(volume) && TextUtil.isEmpty(rate)) {
                        voice.appendChild(doc.createTextNode(text));
                    } else {
                        emotion = doc.createElement("mstts:express-as");
                        // 如果为空 还设置的话会导致role不起作用
                        if (!TextUtil.isEmpty(style)) {
                            emotion.setAttribute("style", style);
                        }
                        emotion.setAttribute("role", role);

                        if (!TextUtil.isEmpty(volume) || !TextUtil.isEmpty(rate)) {
                            emotion.setAttribute("styledegree", "1");
                            prosody = doc.createElement("prosody");
                            if (!TextUtil.isEmpty(volume)) {
                                prosody.setAttribute("volume", volume);
                            }
                            if (!TextUtil.isEmpty(rate)) {
                                prosody.setAttribute("rate", rate);
                            }
                            if (!TextUtil.isEmpty(pitch)) {
                                prosody.setAttribute("pitch", pitch + "%");
                            }
                            prosody.appendChild(doc.createTextNode(text));

                            emotion.appendChild(prosody);
                        } else {
                            emotion.appendChild(doc.createTextNode(text));
                        }
                        voice.appendChild(emotion);
                    }
                    speak.appendChild(voice);
                } else {
                    return null;
                }
                doc.appendChild(speak);
            }
        } catch (ParserConfigurationException e) {
            log.error("Create ssml document failed: {}", e.getMessage());
            return null;
        }
        return transformDom(doc);
    }


    public static String createDom3(String name, String style, String volume, String rate, String pitch, String styledegree, String role, String text) {
        Document doc = null;
        Element speak, voice, emotion, prosody, p;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            doc = builder.newDocument();
            if (doc != null) {
                speak = doc.createElement("speak");
                speak.setAttribute("version", "1.0");
                speak.setAttribute("xmlns", "http://www.w3.org/2001/10/synthesis");
                speak.setAttribute("xmlns:mstts", "https://www.w3.org/2001/mstts");
                speak.setAttribute("xmlns:emo", "http://www.w3.org/2009/10/emotionml");
                speak.setAttribute("xml:lang", "zh-CN");
//                String[] split = text.split("[！!？?:；、丶`。.，,;’\"‘“”]+");
                if (!TextUtil.isEmpty(name)) {
                    voice = doc.createElement("voice");
                    p = doc.createElement("p");
                    voice.appendChild(p);
                    voice.setAttribute("name", name);
                    if (TextUtil.isEmpty(style) && TextUtil.isEmpty(role) && TextUtil.isEmpty(volume) && TextUtil.isEmpty(pitch) && TextUtil.isEmpty(rate)) {
//                        for (int i = 0; i < split.length; i++) {
//                            String s1 = split[i];
//                            if (!TextUtil.isEmpty(s1)) {
//                                Element breakValue = doc.createElement("break");
//                                breakValue.setAttribute("time", "200ms");
////                                Element phoneme = doc.createElement("phoneme");
////                                phoneme.setAttribute("alphabet","sapi");
////                                phoneme.setAttribute("ph","zhuó");
////                                phoneme.appendChild(doc.createTextNode(s1));
//                                p.appendChild(doc.createTextNode(s1));
//                                p.appendChild(breakValue);
//                            }
//                        }
                        p.appendChild(doc.createTextNode(text));
                    } else {
                        emotion = doc.createElement("mstts:express-as");
                        p.appendChild(emotion);
                        // 如果为空 还设置的话会导致role不起作用
                        if (!TextUtil.isEmpty(style)) {
                            emotion.setAttribute("style", style);
                        }
                        emotion.setAttribute("role", role);


                        if (!TextUtil.isEmpty(volume) || !TextUtil.isEmpty(rate) || !TextUtil.isEmpty(pitch)) {
                            emotion.setAttribute("styledegree", styledegree);
                            prosody = doc.createElement("prosody");
                            p.appendChild(prosody);
                            if (!TextUtil.isEmpty(volume)) {
                                prosody.setAttribute("volume", volume);
                            }
                            if (!TextUtil.isEmpty(rate)) {
                                prosody.setAttribute("rate", rate);
                            }
                            if (!TextUtil.isEmpty(pitch)) {
                                prosody.setAttribute("pitch", pitch);
                            }
//                            prosody.setAttribute("volume", volume);
//                            for (int i = 0; i < split.length; i++) {
//                                String s1 = split[i];
//                                if (!TextUtil.isEmpty(s1)) {
//                                    Element breakValue = doc.createElement("break");
//                                    breakValue.setAttribute("time", "200ms");
//                                    prosody.appendChild(doc.createTextNode(s1));
//                                    prosody.appendChild(breakValue);
//
//                                }
//                            }
                            prosody.appendChild(doc.createTextNode(text));
                            emotion.appendChild(prosody);
                        } else {
//                            for (int i = 0; i < split.length; i++) {
//                                String s1 = split[i];
//                                if (!TextUtil.isEmpty(s1)) {
//                                    Element breakValue = doc.createElement("break");
//                                    breakValue.setAttribute("time", "200ms");
//                                    emotion.appendChild(doc.createTextNode(s1));
//                                    emotion.appendChild(breakValue);
//
//                                }
//                            }
                            emotion.appendChild(doc.createTextNode(text));
                        }

                    }
                    speak.appendChild(voice);
                } else {
                    return null;
                }
                doc.appendChild(speak);
            }
        } catch (ParserConfigurationException e) {
            log.error("Create ssml document failed: {}", e.getMessage());
            return null;
        }
        return transformDom(doc);
    }

    public static String createDom4(String name, String style, String volume, String rate,  String pitch,String styledegree,String role, String text) {
        Document doc = null;
        Element speak, voice, emotion, prosody, p;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            doc = builder.newDocument();
            if (doc != null) {
                speak = doc.createElement("speak");
                speak.setAttribute("version", "1.0");
                speak.setAttribute("xmlns", "http://www.w3.org/2001/10/synthesis");
                speak.setAttribute("xmlns:mstts", "https://www.w3.org/2001/mstts");
                speak.setAttribute("xmlns:emo", "http://www.w3.org/2009/10/emotionml");
                speak.setAttribute("xml:lang", "zh-CN");
                String[] split = text.split("[！!？?:；、丶`。.，,;’\"‘“”]+");
                if (!TextUtil.isEmpty(name)) {
                    voice = doc.createElement("voice");
                    p = doc.createElement("p");
                    voice.appendChild(p);
                    voice.setAttribute("name", name);

                    if (TextUtil.isEmpty(style) && TextUtil.isEmpty(role) && TextUtil.isEmpty(volume) && TextUtil.isEmpty(rate)) {
                        for (int i = 0; i < split.length; i++) {
                            String s1 = split[i];
                            if (!TextUtil.isEmpty(s1)) {
                                Element breakValue = doc.createElement("break");
                                breakValue.setAttribute("time","100ms");
                                p.appendChild(doc.createTextNode(s1));
                                if(i!=split.length-1){
                                    p.appendChild(breakValue);
                                }
                            }
                        }
                    } else {
                        emotion = doc.createElement("mstts:express-as");
                        p.appendChild(emotion);
                        // 如果为空 还设置的话会导致role不起作用
                        if (!TextUtil.isEmpty(style)) {
                            emotion.setAttribute("style", style);
                        }
                        emotion.setAttribute("role", role);


                        if (!TextUtil.isEmpty(volume) || !TextUtil.isEmpty(rate)) {
                            emotion.setAttribute("styledegree", "2");
                            prosody = doc.createElement("prosody");
                            p.appendChild(prosody);
                            if (!TextUtil.isEmpty(volume)) {
                                prosody.setAttribute("volume", volume);
                            }
                            if (!TextUtil.isEmpty(rate)) {
                                prosody.setAttribute("rate", rate);
                            }
                            if (!TextUtil.isEmpty(pitch)) {
                                prosody.setAttribute("pitch", pitch + "%");
                            }
//                            prosody.setAttribute("volume", volume);
                            for (int i = 0; i < split.length; i++) {
                                String s1 = split[i];
                                if (!TextUtil.isEmpty(s1)) {
                                    Element breakValue = doc.createElement("break");
                                    breakValue.setAttribute("time","100ms");
                                    prosody.appendChild(doc.createTextNode(s1));
                                    if(i!=split.length-1){
                                        prosody.appendChild(breakValue);
                                    }
                                }
                            }
                            emotion.appendChild(prosody);
                        } else {
                            for (int i = 0; i < split.length; i++) {
                                String s1 = split[i];
                                if (!TextUtil.isEmpty(s1)) {
                                    Element breakValue = doc.createElement("break");
                                    breakValue.setAttribute("time","100ms");
                                    emotion.appendChild(doc.createTextNode(s1));
                                    if(i!=split.length-1){
                                        emotion.appendChild(breakValue);
                                    }
                                }
                            }
                        }

                    }
                    speak.appendChild(voice);
                } else {
                    return null;
                }
                doc.appendChild(speak);
            }
        } catch (ParserConfigurationException e) {
            log.error("Create ssml document failed: {}", e.getMessage());
            return null;
        }
        return transformDom(doc);
    }

    private static String transformDom(Document doc) {
        StringWriter writer = new StringWriter();
        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = tf.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.transform(new DOMSource(doc), new StreamResult(writer));
        } catch (TransformerException e) {
            log.error("Transform ssml document failed: {}", e.getMessage());
            return null;
        }
        return writer.getBuffer().toString().replaceAll("\n|\r", "");
    }

}
